#!/bin/bash

# quit when error
set -e
build_root=$PWD

# Function to check if a command exists
function command_exists {
    command -v "$1" &>/dev/null
}

# Check if sudo is available
if ! command_exists sudo; then
    echo "This script requires sudo privileges."
    exit 1
fi

# Check if git is installed
if ! command_exists git; then
    echo "git is not installed. Please install git first."
    exit 1
fi

# Clone kata-containers if it doesn't exist
if [ ! -e $build_root/kata-containers ]; then
    echo "Cloning kata-containers..."
    git clone https://gitee.com/src-openeuler/kata-containers.git
fi
cd $build_root/kata-containers
echo "Going to kata-containers directory."

# Apply patches if not applied yet
echo "Applying patches..."
./apply-patches
if [[ -f ./patch_flag_h ]];then
       echo "patched!"
    else
       cat $build_root/patches.conf | while read line
       do
          if [[ $line == '' || $line =~ ^\s*# ]]; then
              continue
          fi
          echo "====patch $line======"
          patch -p1 -F1 -s < $build_root/patches/$line
       done
       touch ./patch_flag_h 
fi  
cd $build_root
# Function to configure the build environment
function environment {
    echo "Configuring the build environment..."

    # Install libseccomp-devel
    echo "Installing libseccomp-devel..."
    sudo yum install -y libseccomp-devel

    # Check if Rust is installed by yum, uninstall if necessary
    if rpm -q rustc &>/dev/null; then
        echo "The version of Rust installed by yum is too high. Uninstalling and reinstalling version 1.69.0 using rustup."
        sudo yum remove -y rust cargo
    fi

    # Install rustup if not already installed
    if ! command_exists rustup; then
        echo "Installing rustup..."
        curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    else
        echo "rustup is already installed."
    fi

    # Set default Rust version to 1.69.0
    echo "Setting default Rust version to 1.69.0..."
    rustup default 1.69.0
    echo "Rust default version set."

    # Add RISC-V toolchain target
    echo "Adding RISC-V toolchain target..."
    rustup target add riscv64gc-unknown-linux-gnu

    # Check if Go is installed
    if ! command_exists go; then
        echo "Go is not installed. Installing Go..."

        if [ ! -e $build_root/go_golang ]; then
            echo "Cloning go_golang..."
            git clone https://gitee.com/huang_a/go_golang.git
        fi

        export PATH=$build_root/go_golang/go/bin:$PATH
        chmod +x $build_root/go_golang/go/bin/go
        export GOROOT=$build_root/go_golang/go
        export GOPATH=$build_root/go_golang/golang
        echo "Go environment setup complete."

        # Configure Go Proxy
        echo "Configuring Go Proxy..."
        go env -w GOPROXY=https://goproxy.cn
        echo "Go Proxy configured."
    else
        go version
    fi

    # Install yq
    if ! command_exists yq; then
        echo "Installing yq..."
        go install github.com/mikefarah/yq/v4@latest
        echo "yq installed."
    else
        echo "yq is already installed."
    fi
    #install python packages
    pip install pandas
}

# Function to test libs
function test_libs {
    echo "Running lib tests..."
    cp $build_root/run_libs_test.sh $build_root/count_libs_perf.py $build_root/count_libs_test.py $build_root/performance_counter_920.sh $build_root/kata-containers/src/libs
    cd $build_root/kata-containers/src/libs
    echo "Starting lib test..."
    ./run_libs_test.sh 
    echo "Counting lib performance..."
    python count_libs_test.py
    python count_libs_perf.py
    cp test_result.xlsx $build_root/test_libs_result.xlsx
    cp perf_result.xlsx $build_root/perf_libs_result.xlsx
}

# Function to test agent
function test_agent {
    echo "Running agent tests..."
    cp $build_root/run_agent_test.sh $build_root/count_agent_perf.py $build_root/count_agent_test.py $build_root/performance_counter_920.sh $build_root/kata-containers/src/agent
    cd $build_root/kata-containers/src/agent
    echo "Starting agent test..."
    ./run_agent_test.sh 
    echo "Counting agent performance..."
    python count_agent_test.py
    python count_agent_perf.py
    cp test_result.xlsx $build_root/test_agent_result.xlsx
    cp perf_result.xlsx $build_root/perf_agent_result.xlsx
}

# Function to test runtime
function test_runtime {
    echo "Running runtime tests..."
    cp $build_root/run_runtime_test.sh $build_root/count_runtime_perf.py $build_root/count_runtime_test.py $build_root/performance_counter_920.sh $build_root/kata-containers/src/runtime
    cd $build_root/kata-containers/src/runtime
    echo "Starting runtime test..."
    ./run_runtime_test.sh 
    echo "Counting runtime performance..."
    python count_runtime_test.py
    python count_runtime_perf.py
    cp test_result.xlsx $build_root/test_runtime_result.xlsx
    cp perf_result.xlsx $build_root/perf_runtime_result.xlsx
}

# Function to show help message
function show_help {
    echo "Usage: $0 [OPTIONS]"
    echo "Options:"
    echo "  --environment           Configure the build environment (install dependencies)"
    echo "  --test_libs           Run tests for libs"
    echo "  --test_agent          Run tests for agent"
    echo "  --test_runtime        Run tests for runtime"
    echo "  --h                   Show this help message"
    echo ""
    echo "If no function is specified, all functions will be executed in sequence."
}

# Main script execution
if [ $# -eq 0 ]; then
    echo "No function specified. Executing all functions..."
    environment
    test_libs
    test_agent
    test_runtime
elif [[ "$1" == "--h" ]]; then
    show_help
else
    # Execute specified functions
    for func in "$@"; do
        case "$func" in
            --environment)
                environment
                ;;
            --test_libs)
                test_libs
                ;;
            --test_agent)
                test_agent
                ;;
            --test_runtime)
                test_runtime
                ;;
            *)
                show_help
                exit 1
                ;;
        esac
    done
fi
